unit NodeJSONUtils;

interface

uses
  Vcl.ComCtrls, Data.DBXJSON, System.SysUtils, System.Classes, Data.DBXPlatform;

type

  PNodeInfo = ^TNodeInfo;

  TNodeInfo = record
    NodeName: string;
    NodeType: string;
    NodeDBPath: string; // or connection string
    NodeIP: string;
    NodeAddress: string;
  end;

function Node2JSONList(TopNode: TTreeNode): TJSONObject;
procedure JSONList2Node(var TreeView: TTreeView; JSONObject: TJSONObject;
  TreeNode: TTreeNode);
function GetNodeByText(ATree: TTreeView; AValue: String;
  AVisible: Boolean = true): TTreeNode;


implementation

function Node2JSONList(TopNode: TTreeNode): TJSONObject;
var
  TreeNode: TTreeNode;
  JSONObject, JSONParent: TJSONObject;
  i: Integer;
begin
  JSONParent := TJSONObject.Create;

  for i := 0 to TopNode.Count - 1 do
  begin
    TreeNode := TopNode.Item[i];
    JSONObject := TJSONObject.Create;
    JSONObject.AddPair('NodeName', PNodeInfo(TreeNode.Data)^.NodeName);
    JSONObject.AddPair('NodeType', PNodeInfo(TreeNode.Data)^.NodeType);
    JSONObject.AddPair('NodeDB', PNodeInfo(TreeNode.Data)^.NodeDBPath);
    JSONObject.AddPair('NodeIP', PNodeInfo(TreeNode.Data)^.NodeIP);
    JSONObject.AddPair('NodeAddress', PNodeInfo(TreeNode.Data)^.NodeAddress);
    if TreeNode.Count > 0 then
      JSONObject.AddPair('NodeList', Node2JSONList(TreeNode));
    JSONParent.AddPair('Node ' + IntToStr(TreeNode.AbsoluteIndex), JSONObject);
  end;
  Result := JSONParent;
end;

procedure JSONList2Node(var TreeView: TTreeView; JSONObject: TJSONObject; TreeNode: TTreeNode);
var
  Value, Item: TJSONPair;
  tmpNodeInfo: TStringList;
  Node: TTreeNode;
  NodeInfoPtr: PNodeInfo;
begin
  tmpNodeInfo := TStringList.Create;
  try
    for Value in JSONObject do
    begin
      Node := TreeView.Items.AddChild(TreeNode,
        TJSONPair(Value).JsonString.Value);
      for Item in TJSONObject(TJSONPair(Value).JsonValue) do
      begin
        tmpNodeInfo.Values[TJSONPair(Item).JsonString.Value] := TJSONPair(Item)
          .JsonValue.Value;
        if TJSONPair(Item).JsonString.Value = 'NodeList' then
          JSONList2Node(TreeView, TJSONObject(TJSONPair(Item).JsonValue), Node);
      end;
      New(NodeInfoPtr);
      NodeInfoPtr^.NodeName := tmpNodeInfo.Values['NodeName'];
      NodeInfoPtr^.NodeType := tmpNodeInfo.Values['NodeType'];
      NodeInfoPtr^.NodeDBPath := tmpNodeInfo.Values['NodeDB'];
      NodeInfoPtr^.NodeIP := tmpNodeInfo.Values['NodeIP'];
      NodeInfoPtr^.NodeAddress := tmpNodeInfo.Values['NodeAddress'];
      Node.Data := NodeInfoPtr;
      Node.Text := Format('%s(%s)', [tmpNodeInfo.Values['NodeName'], tmpNodeInfo.Values['NodeIP']]);
    end;
  finally
    tmpNodeInfo.Free;
  end;
end;

function GetNodeByText(ATree: TTreeView; AValue: String;
  AVisible: Boolean = true): TTreeNode;
var
  Node: TTreeNode;
  NodeData: PNodeInfo;
begin
  Result := nil;
  if ATree.Items.Count = 0 then
    Exit;
  Node := ATree.Items[0];
  while Node <> nil do
  begin
    NodeData := PNodeInfo(Node.Data);
    if NodeData <> nil then
    begin
      if UpperCase(NodeData^.NodeAddress) = UpperCase(AValue) then
      begin
        Result := Node;
        if AVisible then
          Result.MakeVisible;
        Break;
      end;
    end;
    Node := Node.GetNext;
  end;
end;

end.
